package cn.xuchunh.guava.base;

import com.google.common.base.Function;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Ints;
import com.sun.org.apache.xpath.internal.operations.Or;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Created by XCH on 2017/3/30.
 *
 * <p>
 * <a href="http://wiki.jikexueyuan.com/project/google-guava-official-tutorial/the-sorting.html">排序器</a>
 *
 * Ordering 把很多基于 Comparator 的静态方法（如 Collections.max）包装为自己的实例方法（非静态方法），
 * 并且提供了链式调用方法，来定制和增强现有的比较器。
 *
 * @author XCH
 * @version 1.0.0-SNAPSHOT
 */
public class LovelyComparation {

    public static void main(String[] args) {

        /* *****************************************创建排序器**************************************** */
        // 对可排序类型做自然排序，如数字按大小，日期按先后排序
        Ordering naturalOrdering = Ordering.natural();

        // 按对象的字符串形式做字典排序[lexicographical ordering]
        Ordering usingToStringOrdering = Ordering.usingToString();

        // 把给定的 Comparator 转化为排序器
        Comparator<String> myComparator = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return Ints.compare(o1.length(), o2.length());
            }
        };
        Ordering fromComparatorOrdering = Ordering.from(myComparator);

        // 直接继承 Ordering
        Ordering<String> byLengthOrdering = new Ordering<String>() {
            @Override
            public int compare(String s, String t1) {
                return Ints.compare(s.length(), t1.length());
            }
        };
        /* *************************************************************************************** */

        Ordering<Foo> ordering = Ordering.natural()
                // 	使用当前排序器，但额外把 null 值排到最前面。
                .nullsFirst()
                // 使用当前排序器，但额外把 null 值排到最后面。
                .nullsLast()
                // 	获取语义相反的排序器
                .reverse()
                // 对集合中元素调用 Function，再按返回值用当前排序器排序。
                .onResultOf(new Function<Foo, String>() {
                    @Override
                    public String apply(Foo foo) {
                        return foo.sortedBy;
                    }
                });
        // 合成另一个比较器，以处理当前排序器中的相等情况。
        ordering.compound(new Comparator<Foo>() {
            @Override
            public int compare(Foo o1, Foo o2) {
                return 1;
            }
        });

        // 	基于处理类型 T 的排序器，返回该类型的可迭代对象 Iterable<T>的排序器。
        Ordering iterableOrdering = ordering.lexicographical();

        Ordering<String> myOrdering = Ordering.natural().nullsFirst().reverse();
        List<String> list = new ArrayList<>();
        list.add("peida");
        list.add("jerry");
        list.add("harry");
        list.add("eva");
        list.add("jhon");
        list.add("neron");
        list.add("jerry");
        // 判断可迭代对象是否已严格按排序器排序
        System.out.println("sortedCopy: " + myOrdering.sortedCopy(list));

        // 获取可迭代对象中最大的k个元素。
        System.out.println("greatestOf: " + myOrdering.greatestOf(list, list.size() / 2));
        // 获取可迭代对象中最小的k个元素。
        System.out.println("leastOf: " + myOrdering.leastOf(list, list.size() / 2));

        // 判断可迭代对象是否已按排序器排序：允许有排序值相等的元素。isStrictlyOrdered：不允许相同的值
        System.out.println("isOrdered: " + myOrdering.isOrdered(list));

        // 返回两个参数中最小的那个。如果相等，则返回第一个参数。max(E, E)
        System.out.println("min(two params): " + myOrdering.min("peida", "harry"));

        // 返回迭代器中最小的元素。如果可迭代对象中没有元素，则抛出 NoSuchElementException。
        // max(Iterable), min(Iterator), max(Iterator)
        System.out.println("min(iterable): " + myOrdering.min(list));

        // 返回多个参数中最小的那个。如果有超过一个参数都最小，则返回第一个最小的参数. max(E, E, E, ...)
        System.out.println("min(e,e,e,...): " + myOrdering.min(list.get(0), list.get(1), list.get(2)));
    }

}
